﻿using System;
using System.Collections.Generic;

using System.Text;
using System.IO;

namespace Ession
{
    public class FileTool
    {


        /// <summary>
        /// 生成一个文件,该文件与源文件有相同的长度,并且内容有一定长度是相同的
        /// </summary>
        /// <param name="sourceFileName">源文件</param>
        /// <param name="desFileName">生成的目标文件</param>
        /// <param name="copyLength">有多少长度的内容是相同的</param>
        public void CopyPartFile(string sourceFileName, string desFileName, int copyLength)
        {
            using (FileStream FirstFile = new FileStream(sourceFileName, FileMode.Open, FileAccess.Read))
            {
                using (FileStream DesFile = new FileStream(desFileName, FileMode.Create, FileAccess.ReadWrite))
                {
                    DesFile.SetLength(FirstFile.Length);
                    int i = 0;
                    while (i < copyLength &&i<FirstFile.Length)
                    {
                        byte b = (byte)FirstFile.ReadByte();
                        DesFile.WriteByte(b);
                        i++;
                    }
                    DesFile.Flush();

                }
            }
        }
        /// <summary>
        /// 生成一个文件,该文件与源文件有相同的长度,并且内容有一定长度是相同的,从某个起点开始复制.
        /// </summary>
        /// <param name="sourceFileName">源文件</param>
        /// <param name="desFileName">生成的目标文件</param>
        /// <param name="copyLength">有多少长度的内容是相同的</param>
        /// <param name="startPosition">从源文件的何处开始复制</param>
        public void CopyPartFile(string sourceFileName, string desFileName,int startPosition, int copyLength)
        {
            using (FileStream FirstFile = new FileStream(sourceFileName, FileMode.Open, FileAccess.Read))
            {
                
                using (FileStream DesFile = new FileStream(desFileName, FileMode.OpenOrCreate, FileAccess.ReadWrite))
                {
                    DesFile.SetLength(FirstFile.Length);
                    int i = startPosition;
                    FirstFile.Seek(i, SeekOrigin.Begin);
                    DesFile.Seek(i, SeekOrigin.Begin);
                    while (i < copyLength && i < FirstFile.Length)
                    {
                        byte b = (byte)FirstFile.ReadByte();
                        DesFile.WriteByte(b);
                        i++;
                    }
                    DesFile.Flush();

                }
            }
        }

        /// <summary>
        /// 将文件分为两部分
        /// </summary>
        /// <param name="SourcefilePathAndName"></param>
        /// <param name="startByte">分割的起始字节</param>
        /// <param name="destinationFilePathAndName"></param>
        /// <returns></returns>
        public bool CutFileIntoTwoParts(string SourcefilePathAndName, long startByte, string destinationFilePathAndName)
        {
            FileStream fSource;
            FileStream fDest;

            try
            {
                int BufferSize = 20971520;//20MB

                byte[] data = new byte[BufferSize];

                fSource = new FileStream(SourcefilePathAndName, FileMode.OpenOrCreate, FileAccess.ReadWrite);

                long length = fSource.Length;
                fSource.Position = startByte;
                if (File.Exists(destinationFilePathAndName))
                {
                    try
                    {
                        File.Delete(destinationFilePathAndName);
                    }
                    catch (Exception ex)
                    {
                        throw ex;
                        return false;
                    }

                }

                fDest = new FileStream(destinationFilePathAndName, FileMode.OpenOrCreate, FileAccess.ReadWrite);
                int count = 0;
                while ((count = fSource.Read(data, 0, data.Length)) > 0)
                {
                    fDest.Write(data, 0, count);
                }

            }
            catch (Exception ex)
            {
                throw ex;

                return false;
            }

            fSource.Close();
            fDest.Close();
            return true;




        }
        public bool CutFileIntoTwoParts(string SourcefilePathAndName, long startByte, string destinationFilePathAndName, long buffersize)
        {
            FileStream fSource;
            FileStream fDest;

            try
            {


                byte[] data = new byte[buffersize];

                fSource = new FileStream(SourcefilePathAndName, FileMode.OpenOrCreate, FileAccess.ReadWrite);

                long length = fSource.Length;
                fSource.Position = startByte;
                if (File.Exists(destinationFilePathAndName))
                {
                    try
                    {
                        File.Delete(destinationFilePathAndName);
                    }
                    catch (Exception ex)
                    {

                        return false;
                    }

                }

                fDest = new FileStream(destinationFilePathAndName, FileMode.OpenOrCreate, FileAccess.ReadWrite);
                int count = 0;
                while ((count = fSource.Read(data, 0, data.Length)) > 0)
                {
                    fDest.Write(data, 0, count);
                }

            }
            catch (Exception ex)
            {

                return false;
            }

            fSource.Close();
            fDest.Close();
            return true;




        }
        /// <summary>
        /// 将文件分为两部分
        /// </summary>
        /// <param name="SourcefilePathAndName"></param>
        /// <param name="startByte">分割的起始字节</param>
        /// <param name="destinationFileOnePathAndName">文件一名称</param>
        /// <param name="destinationFileTwoPathAndName">文件二名称</param>
        /// <param name="buffersize"></param>
        /// <returns></returns>
        public bool CutFileIntoTwoParts(string SourcefilePathAndName, long startByte, string destinationFileOnePathAndName, string destinationFileTwoPathAndName, long buffersize)
        {
            FileStream fSource;
            FileStream fDestOne;
            FileStream fDestTwo;

            try
            {


                byte[] data = new byte[buffersize];

                fSource = new FileStream(SourcefilePathAndName, FileMode.OpenOrCreate, FileAccess.ReadWrite);

                long length = fSource.Length;

                if (File.Exists(destinationFileOnePathAndName))
                {
                    try
                    {
                        File.Delete(destinationFileOnePathAndName);
                    }
                    catch (Exception ex)
                    {

                        return false;
                    }

                }
                if (File.Exists(destinationFileTwoPathAndName))
                {
                    try
                    {
                        File.Delete(destinationFileTwoPathAndName);
                    }
                    catch (Exception ex)
                    {

                        return false;
                    }

                }

                fDestOne = new FileStream(destinationFileOnePathAndName, FileMode.OpenOrCreate, FileAccess.ReadWrite);

                int ReadAccount = 0;
                int count;
                while (true)
                {
                    count = fSource.Read(data, 0, data.Length);
                    if (count > 0 && ReadAccount < startByte)
                    {
                        ReadAccount += count;
                        fDestOne.Write(data, 0, count);

                    }
                    else if (count > 0)
                    {
                        fDestOne.Write(data, 0, ReadAccount % (data.Length));

                    }
                    else
                    {
                        break;
                    }
                }
                fDestTwo = new FileStream(destinationFileTwoPathAndName, FileMode.OpenOrCreate, FileAccess.ReadWrite);

                fSource.Position = startByte;

                while ((count = fSource.Read(data, 0, data.Length)) > 0)
                {
                    fDestTwo.Write(data, 0, count);
                }





            }
            catch (Exception ex)
            {

                return false;
            }

            fSource.Close();
            fDestOne.Close();
            fDestTwo.Close();
            return true;




        }

        /// <summary>
        /// 合并文件.第一个为要合并成的目标文件,而后面的按顺序加上
        /// </summary>
        /// <param name="firstFileName"></param>
        /// <param name="filePathAndName"></param>
        /// <returns></returns>
        public bool JoinFiles(string firstFileName, string[] filePathAndName)
        {
            FileStream FirstFile = new FileStream(firstFileName, FileMode.Append, FileAccess.Write);
            FileStream tmpFile;
            byte[] data = new byte[1048576];

            try
            {
                for (int i = 0; i < filePathAndName.Length; i++)
                {
                    tmpFile = new FileStream(filePathAndName[i], FileMode.Open, FileAccess.Read);
                    int readCount = 0;
                    while ((readCount = tmpFile.Read(data, 0, data.Length)) > 0)
                    {
                        FirstFile.Write(data, 0, readCount);

                    }
                    tmpFile.Close();
                }

            }
            catch (Exception ex)
            {
                return false;
            }
            FirstFile.Close();

            return true;

        }

        public string ReadFromFile(string fileName)
        {
            try
            {
                FileStream fs = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.Read);
                StreamReader sr = new StreamReader(fs);
                string data = sr.ReadToEnd();

                sr.Close();
                fs.Close();
                return data;
            }
            catch (Exception ex)
            {
                throw ex;
            }


        }
        /// <summary>
        /// 将字符串追加写入文件
        /// </summary>
        /// <param name="fileName"></param>
        /// <param name="data"></param>
        public void WriteIntoFile(string fileName, string data)
        {
            try
            {
                using (FileStream fs = new FileStream(fileName, FileMode.Append, FileAccess.Write))
                {
                    using (StreamWriter sw = new StreamWriter(fs))
                    {
                        sw.WriteLine(data);
                        sw.Flush();
                        sw.Close();
                        fs.Close();
                    }
                }

            }
            catch (Exception ex)
            {
                throw ex;
            }


        }
    }
}
